package com.example;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.example.entity.User;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

/**
 * Java编程的底层，是计算与抽象的能力，面对海量知识，关键是：掌握核心原理，学会组合已有组件，形成自己的解决问题思维模式。
 */

/**
 * 常用对象
 * 类型	        说明
 * JSONObject	单层或嵌套 JSON 对象
 * JSONArray	JSON 数组
 */

/**
 * 常用方法
 * 功能	                方法
 * 对象转 JSON	        toJsonStr(Object)
 * JSON 字符串转对象	    toBean()
 * 创建 JSON 对象	    createObj()
 * 是否是 JSON	        isJson() / isJsonObj()
 */
@SpringBootTest
public class LearnJSONUtil {

    /**
     * JSON ↔ Java 对象（Bean、Map、List）互转
     */

    @Test
    public void test1() {
        // Java 对象转 JSON 字符串
        User tom = new User("Tom", 22);
        String jsonStr = JSONUtil.toJsonStr(tom);
        System.out.println(jsonStr);
    }

    @Test
    public void test2() {
        // JSON 字符串转 Java 对象
        String jsonStr = "{\"name\":\"Alice\",\"age\":20}";
        System.out.println(jsonStr);
        User user = JSONUtil.toBean(jsonStr, User.class);
        System.out.println(user.toString());

        if (JSONUtil.isTypeJSON(jsonStr)) {
            System.out.println("json类型字符串");
            // JSON 字符串转 JSON 对象
            JSONObject jsonObject = JSONUtil.parseObj(jsonStr);
            System.out.println(jsonObject);
        }
    }

    @Test
    public void test3() {
        // 使用 JSONObject 操作字段
        JSONObject json = JSONUtil.createObj()
                .set("name", "Lily")
                .set("age", 18);
        System.out.println(json);
        System.out.println(json.getStr("name")); // Lily
        System.out.println(json.toStringPretty());

        if (JSONUtil.isTypeJSON(String.valueOf(json))) {
            System.out.println("json对象");
            // JSON 对象转 JSON 字符串
            String jsonStr = JSONUtil.toJsonStr(json);
            System.out.println(jsonStr);
        }
    }

    /**
     * JSON 字符串 ⇄ JSON 对象 ⇄ Java 对象 三者之间的关系
     * 类型	        举例	                                        说明
     * Java 对象	    User u = new User("Tom", 18);	            Java 中的类实例
     * JSON 对象	    JSONObject json = JSONUtil.createObj();	    Hutool 中的结构化对象，类似 Map
     * JSON 字符串	"{\"name\":\"Tom\",\"age\":18}"	            可序列化传输的字符串（前后端交互）
     */
    /**
     * 源 → 目标	                方法
     * Java 对象 → JSON 字符串	JSONUtil.toJsonStr(obj)
     * JSON 字符串 → Java 对象	JSONUtil.toBean(str, Class)
     * Java 对象 → JSONObject	JSONUtil.parseObj(obj)
     * JSONObject → Java 对象	JSONUtil.toBean(jsonObj, Class)
     * JSON 字符串 → JSONObject	JSONUtil.parseObj(str)
     * JSONObject → JSON 字符串	jsonObj.toString()
     */
    @Test
    public void test4() {

        // Java 对象 → JSON 字符串（序列化）
        User user1 = new User("Tom", 18);
        String jsonStr1 = JSONUtil.toJsonStr(user1);
        System.out.println(jsonStr1);
        System.out.println("====================");

        // JSON 字符串 → Java 对象（反序列化）
        String jsonStr2 = "{\"name\":\"Tom\",\"age\":18}";
        User user2 = JSONUtil.toBean(jsonStr2, User.class);
        System.out.println(user2);
        System.out.println("====================");

        // Java 对象 → JSONObject（结构化）
        JSONObject jsonObj = JSONUtil.parseObj(user1);
        System.out.println(jsonObj);
        System.out.println("====================");

        // JSONObject → Java 对象
        User user3 = JSONUtil.toBean(jsonObj, User.class);
        System.out.println(user3);
        System.out.println("====================");

        // JSON 字符串 → JSONObject
        String jsonStr3 = "{\"name\":\"Tom\",\"age\":18}";
        JSONObject json = JSONUtil.parseObj(jsonStr3);
        System.out.println("====================");

        // JSONObject → JSON 字符串
        String jsonStr4 = jsonObj.toString();
        System.out.println(jsonStr4);
        System.out.println("====================");

    }

    /**
     * “拿过来直接用”到底是什么？
     * 这其实是现代开发最典型的模式，对应的是两种能力：
     * 1. 组件化开发
     * 你不需要从零实现，比如：
     * 文件上传：用 Spring MultipartFile 就能搞定
     * JWT登录：引个 jjwt 包写几行就能实现令牌认证
     * 这背后的本质是：调用别人已经封装好的API，组合出自己的功能
     * 2. 能力是看得懂 + 用得对
     * “拿来主义”不是“复制粘贴”，而是：
     * 看得懂文档（JavaDoc / 官方示例）
     * 配置得当（比如Spring的配置、依赖注入）
     * 用得正确（如线程池参数合理、异步回调不阻塞主线程）
     */

    /**
     * 需求	                            方法
     * JSON 数组字符串 → List<Java对象>	JSONUtil.toList(JSONUtil.parseArray(json), Class)
     * List<Java对象> → JSON 字符串	    JSONUtil.toJsonStr(list)
     * 遍历 JSONArray	                arr.getJSONObject(i)，然后提取字段
     * 构造 JSONArray	                JSONUtil.createArray().add(...).add(...)
     */
    @Test
    public void test5() {

        /**
         * JSON 数组字符串 → List<Java 对象>
         * parseArray() 把字符串转成 JSONArray
         * toList(..., Class) 转为具体的 Java 类型集合
         */
        // JSON 数组字符串
        String jsonArrayStr = "[{\"name\":\"Tom\",\"age\":18},{\"name\":\"Alice\",\"age\":20}]";
        // JSON 对象数组
//        JSONArray jsonArray = JSONUtil.parseArray(jsonArrayStr);
        // List<Java 对象>
        List<User> userList = JSONUtil.toList(jsonArrayStr, User.class);
        System.out.println(jsonArrayStr);
//        System.out.println(jsonArray);
        System.out.println(userList);
        System.out.println("=================");

        /**
         * List<Java对象> → JSON 字符串
         */
        // List<Java 对象>
        List<User> users = ListUtil.of(new User("Tom", 18), new User("Alice", 20));
        // JSON 数组字符串
        String jsonStr = JSONUtil.toJsonStr(users);
        System.out.println(users);
        System.out.println(jsonStr);
        System.out.println("=================");

        /**
         * 直接构造 JSONArray、访问元素
         */
        // JSON 对象数组
        JSONArray arr = JSONUtil.createArray()
                .set(JSONUtil.createObj().set("name", "Tom").set("age", 18))
                .set(JSONUtil.createObj().set("name", "Alice").set("age", 20));
        System.out.println(arr);
        JSONObject obj = arr.getJSONObject(0);
        System.out.println(obj.getStr("name")); // Tom

    }

}
